package org.ling.xuan.config;


import com.alibaba.druid.pool.DruidDataSource;
import org.ling.xuan.util.LxIoUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.JdbcTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DbConfig {
    private static volatile JdbcTemplate jdbcTemplate;
    private static volatile DataSource dataSource;
    private static volatile TransactionTemplate transactionTemplate;
    private static final Lock lock = new ReentrantLock();

    public static JdbcTemplate getJdbcTemplate() {
        if (jdbcTemplate == null) {
            lock.lock();
            try {
                if (jdbcTemplate == null) {
                    JdbcTemplate jt = new JdbcTemplate();
                    jt.setDataSource(getDataSource());
                    jdbcTemplate = jt;
                    initTables(jdbcTemplate);
                }
            } finally {
                lock.lock();
            }
        }
        return jdbcTemplate;
    }

    public static TransactionTemplate getTransactionTemplate() {
        if (transactionTemplate == null) {
            lock.lock();
            try {
                if (transactionTemplate == null) {
                    transactionTemplate = new TransactionTemplate(new JdbcTransactionManager(getDataSource()));
                }
            } finally {
                lock.unlock();
            }
        }
        return transactionTemplate;
    }

    public static DataSource getDataSource() {
        if (dataSource == null) {
            lock.lock();
            try {
                if (dataSource == null) {
                    String url = "jdbc:h2:file:" + LxIoUtil.getWorkHome() + "/.lx/h2/lx-db;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1";
                    Properties properties = new Properties();
                    properties.setProperty("druid.stat.mergeSql", "true");
                    properties.setProperty("druid.stat.slowSqlMillis", "500");
                    DruidDataSource druidDataSource = new DruidDataSource();
                    druidDataSource.setDriverClassName("org.h2.Driver");
                    druidDataSource.setPassword("ifm30");
                    druidDataSource.setUrl(url);
                    druidDataSource.setUsername("root");
                    druidDataSource.setDbType("h2");
                    druidDataSource.setInitialSize(3);
                    druidDataSource.setMaxActive(10);
                    druidDataSource.setMaxWait(60000);
                    druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
                    druidDataSource.setMinEvictableIdleTimeMillis(300000);
                    druidDataSource.setValidationQuery("SELECT 1 FROM DUAL");
                    druidDataSource.setTestWhileIdle(true);
                    druidDataSource.setTestOnBorrow(false);
                    druidDataSource.setTestOnReturn(false);
                    druidDataSource.setPoolPreparedStatements(true);
                    druidDataSource.setFilters("stat,wall,slf4j");
                    druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(10);
                    druidDataSource.setUseGlobalDataSourceStat(true);
                    druidDataSource.setConnectProperties(properties);
                    dataSource = druidDataSource;
                }
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("数据源初始化失败");
            } finally {
                lock.unlock();
            }
        }
        return dataSource;
    }

    private static void initTables(JdbcTemplate jdbcTemplate) {
        List<String> ss = getJdbcTemplate().query("SELECT `TABLE_NAME` FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA= ?", (rs, rowNum) -> rs.getString("table_name").toLowerCase(), "PUBLIC");
        if (!ss.contains("local_add")) {
            jdbcTemplate.execute(TableConfig.localAdd());
        }
        if (!ss.contains("mark_file")) {
            jdbcTemplate.execute(TableConfig.markFile());
        }
        if (!ss.contains("project_setting")) {
            jdbcTemplate.execute(TableConfig.projectSetting());
        }
        if (!ss.contains("send_record")) {
            jdbcTemplate.execute(TableConfig.sendRecord());
        }
        if (!ss.contains("upload_record")) {
            jdbcTemplate.execute(TableConfig.uploadRecord());
        }
    }


    public static void main(String[] args) {
        DbConfig.getJdbcTemplate().execute("ALTER TABLE local_add ADD COLUMN skip_sql BOOLEAN NOT NULL DEFAULT false");
    }
}
